import cv2
import numpy as np
from pynput.keyboard import Controller, Key
import time
import psutil
import win32gui
import win32process
import mss
import pyautogui  # 用于点击

keyboard = Controller()
sct = mss.mss()

SAVE_DEBUG_IMAGES = True

# HSV颜色范围
blue_lower = np.array([100, 150, 120])
blue_upper = np.array([130, 255, 255])
red_lower1 = np.array([0, 100, 100])
red_upper1 = np.array([10, 255, 255])
red_lower2 = np.array([160, 100, 100])
red_upper2 = np.array([180, 255, 255])

# 判定线设置
judge_line_x_blue = 796
tolerance_blue = 10
judge_line_x_red = 796
tolerance_red = 10

# 尺寸过滤
min_object_size = 20
min_object_area = 500

# ROI 区域
roi_x = 770
roi_y = 217
roi_width = 70
roi_height = 37

# 绘制颜色
draw_blue_color = (255, 0, 0)
draw_red_color = (0, 0, 255)
draw_line_color = (0, 255, 0)
draw_roi_color = (255, 255, 0)
line_thickness = 2
point_radius = 5

# 按键间隔
last_press_time = 0
min_press_delay = 0.6

# exit_play.png 模板匹配参数
exit_template = cv2.imread("../templates/exit_play.png", cv2.IMREAD_COLOR)
exit_threshold = 0.8
diff_threshold = 15  # 图像变化判定阈值
prev_frame = None  # 用于帧差检测

def find_window_by_exe(exe_name):
    def callback(hwnd, result):
        _, pid = win32process.GetWindowThreadProcessId(hwnd)
        try:
            proc = psutil.Process(pid)
            if proc.name().lower() == exe_name.lower() and win32gui.IsWindowVisible(hwnd):
                result.append(hwnd)
        except psutil.NoSuchProcess:
            pass
    hwnds = []
    win32gui.EnumWindows(callback, hwnds)
    return hwnds[0] if hwnds else None

def get_window_rect(hwnd):
    left, top, right, bottom = win32gui.GetWindowRect(hwnd)
    return (left, top, right - left, bottom - top)

def in_range_hsv(img, lower, upper):
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    return cv2.inRange(hsv, lower, upper)

def near_judge_line(x, target_x, tol):
    return abs(x - target_x) < tol

def frame_difference(img1, img2):
    gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
    gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
    diff = cv2.absdiff(gray1, gray2)
    return np.mean(diff)

# 初始化游戏窗口
hwnd = find_window_by_exe("AetherGazer.exe")
if hwnd is None:
    print("未找到游戏窗口 AetherGazer.exe，请确认游戏是否运行")
    exit()
print("已找到游戏窗口，开始运行脚本...")
if not SAVE_DEBUG_IMAGES:
    print("调试图像保存已禁用，以提高速度。")

template_check_interval = 5
last_template_check = 0
template_clicked = False

while True:
    try:
        foreground = win32gui.GetForegroundWindow()
        if foreground != hwnd:
            time.sleep(0.05)
            continue

        left, top, width, height = get_window_rect(hwnd)
        monitor = {"top": top, "left": left, "width": width, "height": height}
        sct_img = sct.grab(monitor)
        frame = np.array(sct_img)
        frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)

        current_time = time.time()

        # 每5秒检测一次模板
        if not template_clicked and (current_time - last_template_check) >= template_check_interval:
            last_template_check = current_time
            result = cv2.matchTemplate(frame, exit_template, cv2.TM_CCOEFF_NORMED)
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
            if max_val >= exit_threshold:
                click_x = left + max_loc[0] + exit_template.shape[1] // 2
                click_y = top + max_loc[1] + exit_template.shape[0] // 2
                time.sleep(3)
                print(f"匹配成功，点击退出按钮 ({click_x}, {click_y})")
                pyautogui.click(click_x, click_y)
                template_clicked = True
                time.sleep(1)
                keyboard.press(Key.esc)
                keyboard.release(Key.esc)
                time.sleep(1)
                keyboard.press(Key.esc)
                keyboard.release(Key.esc)
                print("已按下 ESC 键")

        # ROI提取和颜色检测
        roi_x_safe = max(0, roi_x)
        roi_y_safe = max(0, roi_y)
        roi_width_safe = min(roi_width, width - roi_x_safe)
        roi_height_safe = min(roi_height, height - roi_y_safe)

        roi_frame = frame[roi_y_safe: roi_y_safe + roi_height_safe, roi_x_safe: roi_x_safe + roi_width_safe]
        if roi_frame.shape[0] <= 0 or roi_frame.shape[1] <= 0:
            time.sleep(0.001)
            continue

        mask_blue = in_range_hsv(roi_frame, blue_lower, blue_upper)
        mask_red1 = in_range_hsv(roi_frame, red_lower1, red_upper1)
        mask_red2 = in_range_hsv(roi_frame, red_lower2, red_upper2)
        mask_red = cv2.bitwise_or(mask_red1, mask_red2)

        key_pressed_this_frame = False

        # 蓝色检测
        contours_blue, _ = cv2.findContours(mask_blue, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
        for cnt_roi in contours_blue:
            x_roi, y_roi, w, h = cv2.boundingRect(cnt_roi)
            if w < min_object_size or h < min_object_size or w * h < min_object_area:
                continue
            center_x_roi = x_roi + w // 2
            actual_center_x = roi_x_safe + center_x_roi
            if near_judge_line(actual_center_x, judge_line_x_blue, tolerance_blue):
                if not key_pressed_this_frame and (current_time - last_press_time >= min_press_delay):
                    last_press_time = current_time
                    keyboard.press('u')
                    keyboard.release('u')
                    print("按下 U")
                    key_pressed_this_frame = True
                    break

        # 红色检测
        if not key_pressed_this_frame:
            contours_red, _ = cv2.findContours(mask_red, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
            for cnt_roi in contours_red:
                x_roi, y_roi, w, h = cv2.boundingRect(cnt_roi)
                if w < min_object_size or h < min_object_size or w * h < min_object_area:
                    continue
                center_x_roi = x_roi + w // 2
                actual_center_x = roi_x_safe + center_x_roi
                if near_judge_line(actual_center_x, judge_line_x_red, tolerance_red):
                    if not key_pressed_this_frame and (current_time - last_press_time >= min_press_delay):
                        last_press_time = current_time
                        keyboard.press('i')
                        keyboard.release('i')
                        print("按下 I")
                        key_pressed_this_frame = True
                        break

        time.sleep(0.01)

    except Exception as e:
        print("错误:", e)
        time.sleep(1)
